Intro

Goal: decide number of pops, maternal families, etc. Then planting design. Parameters: maximize number of pops, then number of maternal families. Plant 2000.

library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ───────────────────────────────────────── tidyverse 1.3.1 ──
✓ ggplot2 3.3.5     ✓ purrr   0.3.4
✓ tibble  3.1.6     ✓ dplyr   1.0.8
✓ tidyr   1.2.0     ✓ stringr 1.4.0
✓ readr   2.1.2     ✓ forcats 0.5.1
── Conflicts ──────────────────────────────────────────── tidyverse_conflicts() ──
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
library(googlesheets4)
library(ggforce)

is.even <- function(x) x%%2 == 0

get data on pops and families

pops <- read_sheet("https://docs.google.com/spreadsheets/d/1dif9Y5hbkSa56Bgonj04-jXh8jNc6f13RBS6BPUf1IQ",
                   skip=1,
                   na=c("NA", ""),
                   col_types = c("ciiicccc"),
                   .name_repair = "universal") %>%
  mutate(approx.number.seeds = as.integer(str_remove_all(approx.number.seeds,"[^0-9]")))
Is it OK to cache OAuth access credentials in the folder ~/Library/Caches/gargle
between R sessions?

1: Yes
2: No
1
Waiting for authentication in browser...
Press Esc/Ctrl + C to abort
Authentication complete.
✓ Reading from Int Bio parents seed stock.
✓ Range 2:5000000.
New names:
• `parent pop` -> `parent.pop`
• `collection year` -> `collection.year`
• `maternal families` -> `maternal.families`
• `approx number seeds` -> `approx.number.seeds`
• `collection priority?` -> `collection.priority.`
• `on climate PCA?` -> `on.climate.PCA.`
pops

filter to one entry per pop, etc

pops.filtered <- pops %>% group_by(parent.pop) %>% slice_max(order_by=maternal.families) %>%
  filter(approx.number.seeds >= 100) %>%
  filter(!(parent.pop %in% c("HH", "RB"))) # old seed

pops.filtered %>% arrange(maternal.families)
sum(pops.filtered$maternal.families>=8)
[1] 21
sum(pops.filtered$maternal.families>=15)
[1] 18

Scenario 1:

Plant 21 pops * 8 families * 12 reps (= 2016 plants)

Scenario 2:

Plant 11 pops * 15 families * 12 reps (= 1980 plants)

Scenario 3:

3 mfs from WV, 4 mfs WR and 7 mfs from everyone else

total mfs = 3+4+721 = 168 13 reps (= 2002 plants)

planting grid

2000 plants. think of 10 blocks of 200

200 = 4*50

plan 1

Create grid

plants <- 2000
blocks <- 10
columns <- 4
rows <- plants/blocks/columns
size <- 20 # plant diameter
radius <- size/2 
aisle <- 90

plan1 <- expand_grid(block=LETTERS[1:blocks],
                     column=1:columns,
                     row=1:rows,
                     radius=radius)

plan1

add positions

column_offset <- sqrt((2*radius)^2 - radius^2) # Pythagorean theorem for offset spacing
plan1 <- plan1 %>%
  mutate(y_pos=ifelse(is.even(column),
                      row*size,
                      row*size-radius),
         x_pos=ifelse(column==1,
                      radius,
                      radius+(column-1)*column_offset))
plan1
plan1 %>% #filter(block=="A", row <6) %>%
  ggplot(aes(x0=x_pos, y0=y_pos, r=radius)) +
  geom_circle(fill="lightgreen", alpha=.25) + 
  coord_equal() +
  facet_wrap(~block, ncol = 10)

update to position blocks

# only offset x_positions (1 "row" of blocks)
plan1 <- plan1 %>%
  mutate(block_x_offset = as.integer(as.factor(block))-1,
    block_x_offset = block_x_offset* (aisle + size + (columns-1)*column_offset))

plan1 %>% #filter(block=="A", row <6) %>%
  ggplot(aes(x0=x_pos+block_x_offset, y0=y_pos, r=radius)) +
  geom_circle(fill="lightgreen", alpha=.25) + 
  coord_equal() 

LS0tCnRpdGxlOiAiQ29tbW9uIEdhcmRlbiBEZXNpZ24iCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMjIEludHJvCgpHb2FsOiBkZWNpZGUgbnVtYmVyIG9mIHBvcHMsIG1hdGVybmFsIGZhbWlsaWVzLCBldGMuICBUaGVuIHBsYW50aW5nIGRlc2lnbi4KUGFyYW1ldGVyczogbWF4aW1pemUgbnVtYmVyIG9mIHBvcHMsIHRoZW4gbnVtYmVyIG9mIG1hdGVybmFsIGZhbWlsaWVzLiAgUGxhbnQgMjAwMC4KCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShnb29nbGVzaGVldHM0KQpsaWJyYXJ5KGdnZm9yY2UpCgppcy5ldmVuIDwtIGZ1bmN0aW9uKHgpIHglJTIgPT0gMApgYGAKCiMjIGdldCBkYXRhIG9uIHBvcHMgYW5kIGZhbWlsaWVzCgpgYGB7cn0KcG9wcyA8LSByZWFkX3NoZWV0KCJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xZGlmOVk1aGJrU2E1NkJnb25qMDQtalhoOGpOYzZmMTNSQlM2QlBVZjFJUSIsCiAgICAgICAgICAgICAgICAgICBza2lwPTEsCiAgICAgICAgICAgICAgICAgICBuYT1jKCJOQSIsICIiKSwKICAgICAgICAgICAgICAgICAgIGNvbF90eXBlcyA9IGMoImNpaWljY2NjIiksCiAgICAgICAgICAgICAgICAgICAubmFtZV9yZXBhaXIgPSAidW5pdmVyc2FsIikgJT4lCiAgbXV0YXRlKGFwcHJveC5udW1iZXIuc2VlZHMgPSBhcy5pbnRlZ2VyKHN0cl9yZW1vdmVfYWxsKGFwcHJveC5udW1iZXIuc2VlZHMsIlteMC05XSIpKSkKCnBvcHMKYGBgCiMjIGZpbHRlciB0byBvbmUgZW50cnkgcGVyIHBvcCwgZXRjCgpgYGB7cn0KcG9wcy5maWx0ZXJlZCA8LSBwb3BzICU+JSBncm91cF9ieShwYXJlbnQucG9wKSAlPiUgc2xpY2VfbWF4KG9yZGVyX2J5PW1hdGVybmFsLmZhbWlsaWVzKSAlPiUKICBmaWx0ZXIoYXBwcm94Lm51bWJlci5zZWVkcyA+PSAxMDApICU+JQogIGZpbHRlcighKHBhcmVudC5wb3AgJWluJSBjKCJISCIsICJSQiIpKSkgIyBvbGQgc2VlZAoKcG9wcy5maWx0ZXJlZCAlPiUgYXJyYW5nZShtYXRlcm5hbC5mYW1pbGllcykKYGBgCgpgYGB7cn0Kc3VtKHBvcHMuZmlsdGVyZWQkbWF0ZXJuYWwuZmFtaWxpZXM+PTgpCmBgYAoKYGBge3J9CnN1bShwb3BzLmZpbHRlcmVkJG1hdGVybmFsLmZhbWlsaWVzPj0xNSkKYGBgCgojIyMgU2NlbmFyaW8gMToKClBsYW50IDIxIHBvcHMgKiA4IGZhbWlsaWVzICogMTIgcmVwcyAoPSAyMDE2IHBsYW50cykKCiMjIyBTY2VuYXJpbyAyOgoKUGxhbnQgMTEgcG9wcyAqIDE1IGZhbWlsaWVzICogMTIgcmVwcyAoPSAxOTgwIHBsYW50cykKCiMjIyBTY2VuYXJpbyAzOgoKMyBtZnMgZnJvbSBXViwgNCBtZnMgV1IgYW5kIDcgbWZzIGZyb20gZXZlcnlvbmUgZWxzZQoKdG90YWwgbWZzID0gMys0KzcqMjEgPSAxNjggKiAxMyByZXBzICg9IDIwMDIgcGxhbnRzKQoKIyMgcGxhbnRpbmcgZ3JpZAoKMjAwMCBwbGFudHMuICB0aGluayBvZiAxMCBibG9ja3Mgb2YgMjAwCgoyMDAgPSA0KjUwCgojIyMgcGxhbiAxCgpDcmVhdGUgZ3JpZApgYGB7cn0KcGxhbnRzIDwtIDIwMDAKYmxvY2tzIDwtIDEwCmNvbHVtbnMgPC0gNApyb3dzIDwtIHBsYW50cy9ibG9ja3MvY29sdW1ucwpzaXplIDwtIDIwICMgcGxhbnQgZGlhbWV0ZXIKcmFkaXVzIDwtIHNpemUvMiAKYWlzbGUgPC0gOTAKCnBsYW4xIDwtIGV4cGFuZF9ncmlkKGJsb2NrPUxFVFRFUlNbMTpibG9ja3NdLAogICAgICAgICAgICAgICAgICAgICBjb2x1bW49MTpjb2x1bW5zLAogICAgICAgICAgICAgICAgICAgICByb3c9MTpyb3dzLAogICAgICAgICAgICAgICAgICAgICByYWRpdXM9cmFkaXVzKQoKcGxhbjEKYGBgCgphZGQgcG9zaXRpb25zCmBgYHtyfQpjb2x1bW5fb2Zmc2V0IDwtIHNxcnQoKDIqcmFkaXVzKV4yIC0gcmFkaXVzXjIpICMgUHl0aGFnb3JlYW4gdGhlb3JlbSBmb3Igb2Zmc2V0IHNwYWNpbmcKcGxhbjEgPC0gcGxhbjEgJT4lCiAgbXV0YXRlKHlfcG9zPWlmZWxzZShpcy5ldmVuKGNvbHVtbiksCiAgICAgICAgICAgICAgICAgICAgICByb3cqc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgIHJvdypzaXplLXJhZGl1cyksCiAgICAgICAgIHhfcG9zPWlmZWxzZShjb2x1bW49PTEsCiAgICAgICAgICAgICAgICAgICAgICByYWRpdXMsCiAgICAgICAgICAgICAgICAgICAgICByYWRpdXMrKGNvbHVtbi0xKSpjb2x1bW5fb2Zmc2V0KSkKcGxhbjEKYGBgCgpgYGB7ciwgZmlnLndpZHRoPTEwfQpwbGFuMSAlPiUgI2ZpbHRlcihibG9jaz09IkEiLCByb3cgPDYpICU+JQogIGdncGxvdChhZXMoeDA9eF9wb3MsIHkwPXlfcG9zLCByPXJhZGl1cykpICsKICBnZW9tX2NpcmNsZShmaWxsPSJsaWdodGdyZWVuIiwgYWxwaGE9LjI1KSArIAogIGNvb3JkX2VxdWFsKCkgKwogIGZhY2V0X3dyYXAofmJsb2NrLCBuY29sID0gMTApCgpgYGAKdXBkYXRlIHRvIHBvc2l0aW9uIGJsb2NrcwpgYGB7ciwgZmlnLndpZHRoPTEyfQojIG9ubHkgb2Zmc2V0IHhfcG9zaXRpb25zICgxICJyb3ciIG9mIGJsb2NrcykKcGxhbjEgPC0gcGxhbjEgJT4lCiAgbXV0YXRlKGJsb2NrX3hfb2Zmc2V0ID0gYXMuaW50ZWdlcihhcy5mYWN0b3IoYmxvY2spKS0xLAogICAgYmxvY2tfeF9vZmZzZXQgPSBibG9ja194X29mZnNldCogKGFpc2xlICsgc2l6ZSArIChjb2x1bW5zLTEpKmNvbHVtbl9vZmZzZXQpKQoKcGxhbjEgJT4lICNmaWx0ZXIoYmxvY2s9PSJBIiwgcm93IDw2KSAlPiUKICBnZ3Bsb3QoYWVzKHgwPXhfcG9zK2Jsb2NrX3hfb2Zmc2V0LCB5MD15X3Bvcywgcj1yYWRpdXMpKSArCiAgZ2VvbV9jaXJjbGUoZmlsbD0ibGlnaHRncmVlbiIsIGFscGhhPS4yNSkgKyAKICBjb29yZF9lcXVhbCgpIApgYGAKCg==